#ifndef _JANNA_PLUGIN_MANAGER_H_
#define _JANNA_PLUGIN_MANAGER_H_

#include <log_util.h>

#include <QDir>
#include <QJsonArray>
#include <QJsonObject>
#include <QMap>
#include <QString>

#include "janna/janna_plugin_interface.h"
#include "janna/janna_type.h"

class PluginManager : public QObject {
    Q_OBJECT

public:
    static PluginManager* getInstance();

private:
    PluginManager();
    static PluginManager*           plugin_manager_self;
    std::shared_ptr<spdlog::logger> log;

private:
    /**
     * @brief 缓存所有插件
     */
    QMap<QString, JannaPluginInterface*> m_plugin_map;

    /**
     * @brief 加载单个插件
     * 
     * @param pluginPath 插件路径
     * @return true 加载成功
     * @return false 加载失败
     */
    bool loadSinglePlugin(QString pluginPath);

    /**
     * @brief 解析插件元数据
     * 
     * @param currPlugin 当前加载的插件
     * @param metadata 插件元数据
     * @return true 解析成功
     * @return false 解析失败
     */
    bool parseMetadata(JannaPluginInterface* currPlugin, QJsonObject metadata);

    /**
     * @brief 解析插件配置文件
     * 
     * @param pluginConfigPath 插件配置文件路径 
     * @return QJsonArray 插件列表配置信息
     */
    QJsonArray parsePluginsConfig(QString pluginConfigPath);

public:
    /**
     * @brief 加载插件列表
     * 
     * @param pluginPath 插件列表配置文件路径
     */
    void loadPlugins(QString pluginPath);

public slots:
    /**
     * @brief 订阅 pubsub 消息
     * 
     * @param topic 主题
     * @param param 参数
     */
    void subscribe(const JannaTopic& topic, const QMap<QString, QVariant>& param);
};

#endif
